import { DlJson } from '../DlJson';
import { TypeConstants } from '../TypeConstants';
import { ReaderIn } from '../ReaderIn';
import { ITypeAdapter } from './ITypeAdapter';
import { WriterOut } from '../WriterOut';

export class ObjectTypeAdapter implements ITypeAdapter {
  read(readerIn: ReaderIn): ReaderIn {
    let target = readerIn.getTarget()
    if (target instanceof DlJson) {
      let arrayKeys = Object.keys(target);
      if (arrayKeys.length > 0) {
        Object.entries(readerIn.getJson()).forEach(([jsonKey, jsonValue]) => {
          arrayKeys.forEach(targetKey => {
            //匹配到就赋值
            if (targetKey == jsonKey) {
              //获取target 子项value值
              let targetValue = target[targetKey]
              //判断当前类型，往下分发
              let jsonType = readerIn.getTypeFactory().create(targetValue)
              //获取子项写入
              let itemReader = new ReaderIn(jsonValue, targetValue, readerIn.getTypeFactory(),readerIn.getReadNums())
              //默认数据添加
              this.defaultTargetAdd(itemReader, targetKey, target)
              //赋值
              readerIn.getTarget()[targetKey] = jsonType.read(itemReader).value()
            }
          });
        })
      }
    } else {
      readerIn.setValue({})
      return readerIn
    }
    readerIn.setValue(readerIn.getTarget())
    return readerIn
  }

  write(writerOut: WriterOut): WriterOut {
    let target = writerOut.getTarget()
    let arrayKeys = Object.keys(target);
    //避免子项中有复核类型或数组类型
    let copyTarget = new DlJson()
    if (arrayKeys.length > 0) {
      Object.entries(target).forEach(([jsonKey, jsonValue]) => {
        let type = writerOut.getTypeFactory().create(jsonValue)
        let itemWriteOut = new WriterOut(
          jsonValue, writerOut.getTypeFactory()
        )
        copyTarget[jsonKey] = type.write(itemWriteOut).value()
      })
    }
    writerOut.setWriteValue(copyTarget)
    return writerOut
  }

  typeConstants(): TypeConstants {
    return TypeConstants.TYPE_OBJECT
  }

  /**
   * 默认数据添加
   * @param itemR 子项Writer
   * @param targetKey 当前key
   * @param targetValue target源数据
   */
  private defaultTargetAdd(itemR: ReaderIn, targetKey: string, target: ESObject) {
    let defaultTarget: DlJson | null = null
    if (target instanceof DlJson) {
      defaultTarget = target.defaultReaderTargetData().get(targetKey) ?? null
    }
    itemR.setDefault(defaultTarget)
  }
}